package com.hu.network.task;

import android.content.Context;

import java.util.UUID;
import java.util.concurrent.Future;

import com.hu.network.http.bean.InnerResponseResult;
import com.hu.network.http.request.IHttpRequest;
import com.hu.network.task.exception.TaskException;
import com.hu.network.threadpool.NetMainHandler;
import com.hu.network.threadpool.ThreadPoolUtil;
import com.hu.network.util.NetUtil;
import timber.log.Timber;

/**
 * 说明：
 *
 * @author ： hucanhua
 * @date ： 2017/10/25
 */
public abstract class AbstractTask<V> implements ITask<V> {

    private static final int OTHER_CODE = 10000;
    protected final boolean useHttps;
    protected final String url;
    protected final ITaskCallback<V> iTaskCallback;
    private Context context;
    private Future<V> future;
    private String uuid;
    private InnerResponseResult<V> innerResponseResult;

    public AbstractTask(Context context, boolean useHttps, String url, ITaskCallback<V> iTaskCallback) {
        this.context = context;
        this.useHttps = useHttps;
        this.url = url;
        this.iTaskCallback = iTaskCallback;
        innerResponseResult = new InnerResponseResult<>();
        this.uuid = UUID.randomUUID().toString();
    }

    /**
     * 处理即将发送的网络请求前的事务
     *
     * @return 是否通过
     */
    protected abstract boolean before(InnerResponseResult<V> innerResponseResult);

    protected abstract void after(InnerResponseResult<V> innerResponseResult);

    public String getUuid() {
        return uuid;
    }

    @Override
    public V call() {
        try {
            getRequest().execute(innerResponseResult);
            Timber.e("-----接收到的原始信息为-------\n%s", innerResponseResult.toString());
        } catch (Exception e) {
            innerResponseResult.setCode(OTHER_CODE);
            innerResponseResult.setMessage(e.getMessage());
            innerResponseResult.setHttpSuccess(false);
            e.printStackTrace();
        } finally {
            try {
                NetMainHandler.getInstance().runOnMainThread(new Runnable() {
                    @Override
                    public void run() {
                        onResult(innerResponseResult);
                        onAfter(innerResponseResult);
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return innerResponseResult.getResponseResult();
    }

    protected abstract IHttpRequest<V> getRequest();

    private boolean onBefore(InnerResponseResult<V> innerResponseResult) {
        boolean before = false;
        if (iTaskCallback != null) {
            before = iTaskCallback.onBefore();
        }
        if (before) {
            before = NetUtil.activeNetworkIsAvailable(context);
            if (!before) {
                innerResponseResult.setCode(OTHER_CODE);
                innerResponseResult.setMessage("网络不通");
                return false;
            }
        }
        return before && before(innerResponseResult);
    }

    private void onResult(InnerResponseResult<V> innerResponseResult) {
        if (iTaskCallback != null) {
            iTaskCallback.onResult(innerResponseResult);
        }
    }

    private void onAfter(InnerResponseResult<V> innerResponseResult) {
        after(innerResponseResult);
        if (iTaskCallback != null) {
            iTaskCallback.onAfter();
        }
        future = null;
        context = null;
    }

    @Override
    public final void excute() {
        if (onBefore(innerResponseResult)) {
            future = ThreadPoolUtil.getInstance().excute(this);
        } else {
            onResult(innerResponseResult);
            onAfter(innerResponseResult);
        }
    }

    public void cancel() throws TaskException {
        ThreadPoolUtil.getInstance().cancel(future);
    }

    public interface ITaskCallback<V> {
        boolean onBefore();

        void onResult(InnerResponseResult<V> innerResponseResult);

        void onAfter();
    }


}
